-- This is the template for the testbench for Lab 4.  You should start
-- with this, it will make your life easier.  Before starting on this 
-- lab, make sure you review your notes from the tutorial and read the
-- entire handout carefully.

library ieee;
use ieee.std_logic_1164.all;
use ieee.std_logic_unsigned.all;
library work;
use work.all;

entity tb_processor is
end tb_processor;

architecture behavioural of tb_processor is

	-- Component declaration for the processor entity
	component processor is
	port(  clk, reset: in std_logic;
	       instruction_in: in std_logic_vector(15 downto 0);
	       get_next_instruction: out std_logic;
	       datapath_out: out std_logic_vector(7 downto 0));
		-- Enter the component declaration for processor here
	end component;

	-- Some internal signals
	signal clk, reset, get_next_instruction : std_logic;
	signal instruction_in : std_logic_vector(15 downto 0);
	signal datapath_out : std_logic_vector(7 downto 0);

	-- Constant for the clock period
	constant PERIOD :time := 10 ns;

begin 

	-- Instantiate the processor module here, just as you would
	-- do when describing a structural design.
	-- If you are still unsure, take a look at how the 
	-- testbenches from the previous lab did this
  u0: processor
		    port map ( 
		        clk => clk,
		        reset => reset,
		        get_next_instruction => get_next_instruction,
		        instruction_in => instruction_in,
		        datapath_out => datapath_out);

	-- Never-ending process to generate clock pattern
	clk_gen : process
	begin
		clk <= '0';
		wait for PERIOD/2;
		clk <= '1';
		wait for PERIOD/2;
	end process;
      
	-- Process to generate the input patterns
	stimulus : process
	begin
	       
		wait for PERIOD/4;
		wait for PERIOD;
		reset <= '0';
		wait for PERIOD;
		reset <= '1';
        
		-- wait for_get next_instruction (check on falling edge)
		wait until clk='0' and clk'event and get_next_instruction = '1';
		-- When we see this signal, wait until the next cycle and
		-- then drive the instruction
		wait until clk='0' and clk'event;
		-- LOAD #2, R0 (using the suggested encoding)
		instruction_in <= "01010" & "000" & "00000010";
		
		-- wait for_get next_instruction (check on falling edge)
		-- (REMEMBER: get_next_instruction should only be asserted after
		--            your microprocessor has finished with its current 
		--            instruction, hence a number of clock cycles will 
		--            elapse during this next "wait until" statement)
		
		wait until clk='0' and clk'event and get_next_instruction = '1';
		wait until clk='0' and clk'event;
    -- inc r0, r1
		instruction_in <= "11010" & "001" & "000" & "000" & "00";  
		
	  wait until clk='0' and clk'event and get_next_instruction = '1';
	  wait until clk='0' and clk'event; 
		-- MOVE r1, r2
	  instruction_in <= "11001" & "010" & "000" & "001" & "00"; 
				 
	  wait until clk='0' and clk'event and get_next_instruction = '1';
		-- When we see this signal, wait until the next cycle and
		-- then drive the instruction
	  wait until clk='0' and clk'event;
		-- add r0, r2 -> r3
		instruction_in <= "10110" & "011" & "000" & "010" & "00"; 
		
	  wait until clk='0' and clk'event and get_next_instruction = '1';
	  wait until clk='0' and clk'event; 
	  -- sub r3,r0,r4
		instruction_in <= "10011" & "100" & "011" & "000" & "00"; 
 
	  wait until clk='0' and clk'event and get_next_instruction = '1';
	  wait until clk='0' and clk'event; 
	  -- mul r4, r3, r5
		instruction_in <= "10101" & "101" & "100" & "011" & "00";  

	  wait until clk='0' and clk'event and get_next_instruction = '1';
	  wait until clk='0' and clk'event; 
	  -- and r5, r0, r6
		instruction_in <= "10100" & "110" & "101" & "000" & "00";  

		-- NOTE: for full marks, you will need to simulate more than the provided
		--       instruction. Use your judgement to decide how many test-cases
		--       you will need to demonstrate to the TA (your "customer") that
		--       the design they are paying you to make, works.
		
		
		
		
		
		
		-- wait forever at this point
		-- (NOTE: this does not stop the simulation, but
		--  prevents it from restarting from the beginning again)
		wait;
       
	end process;   

end behavioural;




